package com.mydomain.debtbook;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;

public class ListContactWeightActivity extends ListActivity {

	private SimpleCursorAdapter cursorAdapter;
	private Cursor cursor;
	private Button submit;
	private Button refresh;
	private OnClickListener myClickListener;
	private ListView listView;
	private TextView test;
	private OnItemClickListener myItemClickListener;
	private static HashMap<String, String> weightSwitchMap;
	private HashMap<String, HashMap<String, String>> contactListWeight;
	private HashMap<String, Double> lockedWeight;
	private ArrayList<String> contactList;
	private double debtAmount;
	private double debtSplit;
	private double debtAmountRemain;
	private double debtSplitRemain;
	private HashSet splitable;
	private String focusPerson;
	private ContactWeightAdapter listItemAdapter;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.list_view_contact_weight);
		submit = (Button) findViewById(R.id.lvcw_submitButton);
		refresh = (Button) findViewById(R.id.lvcw_refreshButton);

		weightSwitchMap = new HashMap<String, String>();
		weightSwitchMap.put("$", "%");
		weightSwitchMap.put("%", "#");
		weightSwitchMap.put("#", "$");

		Bundle extras = getIntent().getExtras();
		if (extras != null) {

			boolean noSplitable;

			contactListWeight = (HashMap<String, HashMap<String, String>>) extras
					.get("ContactListWeight");
			contactList = extras.getStringArrayList("ContactList");
			splitable = (HashSet) extras.get("Splitable");

			lockedWeight = new HashMap<String, Double>();
			debtAmount = extras.getDouble("DebtAmount");
			debtAmountRemain = debtAmount;
			debtSplit = myRound(debtAmount / contactList.size());

			if (splitable == null) {
				noSplitable = true;
				splitable = new HashSet();
			} else {
				noSplitable = false;
			}

			for (int i = 0; i < contactList.size(); i++) {
				String person = contactList.get(i);

				if (contactListWeight.get(person).get("weight") == null) {

					if (debtAmount != 0 && noSplitable) {
						splitable.add(person);

					}
				}

				else if (contactListWeight.get(person).get("weight").length() == 0
						&& noSplitable) {

					if (debtAmount != 0) {

						splitable.add(person);
					}

				} else if (contactListWeight.get(person).get("weight").length() != 0
						&& debtAmount != 0) {

					lockedWeight
							.put(person,
									myRound(convertWeightUnit(
											contactListWeight.get(person).get(
													"weight"),
											contactListWeight.get(person).get(
													"weightUnit"), "$")));

					if (noSplitable) {
						debtAmountRemain = debtAmountRemain
								- myRound(convertWeightUnit(
										contactListWeight.get(person).get(
												"weight"),
										contactListWeight.get(person).get(
												"weightUnit"), "$"));
					}

				}

			}

			if (debtAmount != 0 && noSplitable) {
				debtSplitRemain = debtAmountRemain / splitable.size();

				String person;

				Iterator myIterator = splitable.iterator();

				while (myIterator.hasNext()) {

					person = myIterator.next().toString();
					contactListWeight.get(person).put("weight",
							String.valueOf(debtSplitRemain));
					contactListWeight.get(person).put("weightUnit", "$");

				}

			}

		}

		else {
			finish();
		}

		myClickListener = new OnClickListener() {
			@Override
			public void onClick(View v) {

				if (v == submit) {
					submit();
				} else if (v == refresh) {
					refreshDebts();
				}

			}
		};

		submit.setOnClickListener(myClickListener);
		refresh.setOnClickListener(myClickListener);
		showContacts();
		getListView().setOnItemClickListener(myItemClickListener);

	}

	private void refreshDebts() {

		Set<String> keySet = lockedWeight.keySet();
		Iterator myKeyIter = keySet.iterator();
		debtAmountRemain = debtAmount;
		String person;

		while (myKeyIter.hasNext()) {
			debtAmountRemain = debtAmountRemain
					- lockedWeight.get(myKeyIter.next());
		}

		debtSplitRemain = debtAmountRemain / splitable.size();

		Iterator myIterator = splitable.iterator();

		while (myIterator.hasNext()) {
			person = myIterator.next().toString();

			contactListWeight.get(person).put("weight",
					String.valueOf(debtSplitRemain));
			contactListWeight.get(person).put("weightUnit", "$");

		}

		listItemAdapter.notifyDataSetChanged();
	}

	private double myRound(double input) {
		return (double) Math.round(input * 100) / 100;
	}

	private double convertWeightUnit(String inputStr, String unitFrom,
			String unitTo) {

		double input;

		if (inputStr != null && inputStr.length() != 0) {
			input = Double.valueOf(inputStr);
		} else {
			return -1;
		}

		if (unitFrom == "$" && unitTo == "%") {

			return input * 100 / debtAmount;

		} else if (unitFrom == "$" && unitTo == "#") {

			return input / debtSplit;

		} else if (unitFrom == "%" && unitTo == "$") {

			return input / 100 * debtAmount;

		} else if (unitFrom == "%" && unitTo == "#") {

			return input / 100 * debtAmount / debtSplit;

		} else if (unitFrom == "#" && unitTo == "%") {

			return input * debtSplit / debtAmount;

		} else if (unitFrom == "#" && unitTo == "$") {

			return input * debtSplit;
		}

		return input;
	}

	private void submit() {

		Intent returnIntent = new Intent();
		returnIntent.putExtra("ContactList", contactList);
		returnIntent.putExtra("ContactListWeight", contactListWeight);
		returnIntent.putExtra("Splitable", splitable);
		setResult(RESULT_OK, returnIntent);
		finish();
	}

	private void back() {
		finish();
	}

	private class ContactWeightAdapter extends ArrayAdapter<String> {

		private ArrayList<String> contactList;
		private LayoutInflater mInflater;
		private String[] weightList;
		private HashMap<String, String> weightMap;

		public ContactWeightAdapter(Context context, int textViewResourceId,
				ArrayList<String> items) {
			super(context, textViewResourceId, items);
			mInflater = LayoutInflater.from(context);
			this.contactList = items;
			weightMap = new HashMap<String, String>();

		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {

			final ViewHolder holder;
			if (convertView == null) {

				convertView = mInflater.inflate(R.layout.list_contact_weight,
						null);
				holder = new ViewHolder();
				holder.name = (TextView) convertView
						.findViewById(R.id.lcw_name);
				holder.weightUnit = (TextView) convertView
						.findViewById(R.id.lcw_weight_unit);
				holder.weight = (EditText) convertView
						.findViewById(R.id.lcw_weight);
				convertView.setTag(holder);

				holder.weight.addTextChangedListener(new TextWatcher() {

					@Override
					public void afterTextChanged(Editable arg0) {

						if (arg0.length() != 0 && holder.weight.hasFocus()) {

							String person = holder.name.getText().toString();

							if (splitable.contains(person)) {
								splitable.remove(person);
							}

							if (splitable.size() == 0) {

								for (int i = 0; i < contactList.size(); i++) {
									splitable.add(contactList.get(i));
								}

								lockedWeight.clear();

							}

							lockedWeight.put(person,
									Double.valueOf(arg0.toString()));
							contactListWeight.get(person).put(
									"weight",
									String.format("%.2f",
											Double.valueOf(arg0.toString())));

						}
					}

					@Override
					public void beforeTextChanged(CharSequence arg0, int arg1,
							int arg2, int arg3) {
					}

					@Override
					public void onTextChanged(CharSequence s, int start,
							int before, int count) {

					}

				});

				holder.weight.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						v.requestFocus();
					}

				});

				holder.weightUnit.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {

						String oldUnit = ((TextView) v).getText().toString();
						String person = holder.name.getText().toString();

						((TextView) v).setText(weightSwitchMap.get(oldUnit));

						contactListWeight.get(person).put("weightUnit",
								((TextView) v).getText().toString());

						if (holder.weight.getText().toString().length() != 0) {

							contactListWeight.get(person).put(
									"weight",
									String.format(
											"%.2f",
											convertWeightUnit(holder.weight
													.getText().toString(),
													oldUnit, weightSwitchMap
															.get(oldUnit))));
						}

						listItemAdapter.notifyDataSetChanged();

					}
				});

			} else {
				holder = (ViewHolder) convertView.getTag();
			}

			String person = contactList.get(position);
			if (person != null) {

				holder.name.setText(person);

				if (contactListWeight.get(person).containsKey("weight")) {

					if (contactListWeight.get(person).get("weight").length() == 0) {
						holder.weight.setText("");
					} else {

						holder.weight.setText(String.format("%.2f", Double
								.valueOf(contactListWeight.get(person).get(
										"weight"))));

						if (splitable.contains(person)) {
							holder.weight.setTextColor(Color.GRAY);
						} else {
							holder.weight.setTextColor(Color.BLACK);
						}

					}
				} else {
					holder.weight.setText("");
				}

				if (contactListWeight.get(person).containsKey("weightUnit")) {

					holder.weightUnit.setText(String.valueOf(contactListWeight
							.get(person).get("weightUnit")));

				} else {
					holder.weightUnit.setText("$");
				}

				holder.weight.clearFocus();

			}
			return convertView;
		}

		class ViewHolder {
			TextView weightUnit;
			TextView name;
			EditText weight;
		}

	}

	private void showContacts() {

		listItemAdapter = new ContactWeightAdapter(this,
				R.layout.list_contact_weight, contactList);
		this.setListAdapter(listItemAdapter);

	}

}
